import { WebIO } from '@gltf-transform/core';
import { EXTTextureWebP, KHRMaterialsSpecular, KHRONOS_EXTENSIONS, KHRTextureTransform } from '@gltf-transform/extensions';
import { center, flatten, quantize, simplify, weld } from '@gltf-transform/functions';
import draco3d from 'draco3dgltf';
import { MeshoptSimplifier, MeshoptEncoder } from 'meshoptimizer';

// obj 模型优化方法
// const miniGLB = await optimizeGlb.optimize(glb);
class OptimizeGlb {

    constructor() { }

    webIO!: WebIO;

    // 优化方法
    async optimize(glbFile: File) {

        if (!this.webIO) {
            this.webIO = new WebIO({ credentials: 'include' })
                .registerExtensions(KHRONOS_EXTENSIONS)
                .registerExtensions([EXTTextureWebP, KHRTextureTransform, KHRMaterialsSpecular])
                .registerDependencies({
                    // 'draco3d.encoder': await draco3d.createEncoderModule(),
                    'draco3d.decoder': await draco3d.createDecoderModule(),
                });
        }

        await MeshoptEncoder.ready;

        let document = await this.webIO.read(URL.createObjectURL(glbFile)); //读取glb为Document

        // 移除 Draco 扩展并解压几何体
        document.getRoot().listExtensionsUsed()
            .filter(ext => ext.extensionName === 'KHR_draco_mesh_compression')
            .forEach(ext => ext.dispose());

        await document.transform(
            center({ pivot: 'center' }),//居中
            weld({}), // 按照官方文件建议减面前先做焊接操作
            simplify({ // 减面
                simplifier: MeshoptSimplifier,
                ratio: 0.1,
                error: 0.001
            }),
            flatten(), // 扁平化
            quantize({ // 降低
                quantizePosition: 14,
                quantizeNormal: 10,
                quantizeTexcoord: 10
            }),
        );

        const glbUint8Array = await this.webIO.writeBinary(document); // 转化为Uint8Array格式

        const blob = new Blob([glbUint8Array], {
            type: 'model/gltf-binary' // GLB 的 MIME 类型
        });

        // 2. 创建 File 对象
        const fileName = 'optimized_model.glb'; // 自定义文件名
        const file = new File([blob], fileName, {
            type: 'model/gltf-binary', // 可选，默认继承 Blob 的 type
            lastModified: Date.now()   // 可选，最后修改时间
        });

        return file;
    }

}

const optimizeGlb = new OptimizeGlb();

export default optimizeGlb;
